#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <gmp.h>
#include <time.h>

int main(int argc, char *argv[]) {
  mpf_t pi;
  mpf_t mpf_pontos_dentro;
  mpf_t mpf_total_pontos;
  clock_t begin, end;
  mpz_t N_ITER;
  mpz_t pontos_dentro;
  mpz_t total_pontos;
  
  FILE *file = fopen("pi_montecarlo_sequencial.txt","w+");

  if(file == NULL) {
    return EXIT_FAILURE;
  }

  mpf_set_default_prec(40000000);

  mpz_init(pontos_dentro);
  mpz_init(total_pontos);
  mpf_init(mpf_pontos_dentro);
  mpf_init(mpf_total_pontos);
  mpf_init(pi);
  mpz_init(N_ITER);
  double x,y;

  if(argc != 2) {
    printf("Usage: %s [n_interations]\n",argv[0]);
    return EXIT_FAILURE;
  } else {
    gmp_sscanf(argv[1],"%Zd",N_ITER);
  }

  srand(time(NULL));

  begin = clock();
  do {
    x = (double)(RAND_MAX - rand())/(double)RAND_MAX;
    y = (double)(RAND_MAX - rand())/(double)RAND_MAX;

    if(x*x + y*y <= 1.0) {
      mpz_add_ui(pontos_dentro,pontos_dentro,1);      
    }

    mpz_add_ui(total_pontos,total_pontos,1);

    mpf_set_z(mpf_pontos_dentro,pontos_dentro);
    mpf_set_z(mpf_total_pontos,total_pontos);

    mpf_div(pi,mpf_pontos_dentro,mpf_total_pontos);
    mpf_mul_ui(pi,pi,4);

    mpf_out_str(file,10,0,pi);
    fprintf(file,"\n");

  } while(mpz_cmp(total_pontos,N_ITER) < 0);


  end = clock();

  printf("Tempo de cálculo: %lf\n",(double)(end - begin)/(double)CLOCKS_PER_SEC);

  fclose(file);

  mpz_clears(pontos_dentro,total_pontos,N_ITER,NULL);
  mpf_clears(pi,mpf_pontos_dentro,mpf_total_pontos,NULL);

  return 0;
}
